/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entityappclient;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.List;
import java.util.Scanner;
import javax.ejb.EJB;
import persistence.entity.Account;
import persistence.entity.Accounttransaction;
import session.stateless.AccountFacadeRemote;
import session.stateless.AccountTransactionHelperRemote;
import session.stateless.CustomerFacadeRemote;

/**
 *
 * @author Craig
 */
public class ATMClient {

    @EJB
    private static AccountTransactionHelperRemote accountTransactionHelper;
    @EJB
    private static CustomerFacadeRemote customerFacade;
    @EJB
    private static AccountFacadeRemote accountFacade;
    private Scanner scan = new Scanner(System.in);
    private int custID;

    public static void main(String[] args) {
        new ATMClient().run();
    }

    public void run() {
        String input;
        //Main loop
        while (true) {
            //Display logo
            System.out.println("     \\`\\/\\/\\/`/     /===========================\\");
            System.out.println("      )======(      |                           |");
            System.out.println("    .'        '.    |          Welcome          |");
            System.out.println("   /    _||__   \\   |        to Swinbank        |");
            System.out.println("  /    (_||_     \\  |                           |");
            System.out.println(" |     __||_)     | |      We !care about       |");
            System.out.println(" |       ||       | |        your safety        |");
            System.out.println(" '.              .' |                           |");
            System.out.println("   '------------'   \\===========================/");
            //Perform login
            custID = getInt("Please enter your customer ID");

            String password = getString("Please enter your password");

            //BUG: Possible bug on authentication, get Null pointer exception
            boolean authenticated = customerFacade.authenticate(custID, password, true);
            if (!authenticated) {
                //Authentication failed, restart loop
                System.out.println("Login Failed");
                continue;
            }

            boolean exit = false;
            while (!exit) {
                //Print main menu
                System.out.println("");
                System.out.println("Main Menu");
                System.out.println("1. View Accounts");
                System.out.println("2. Make a Transaction");
                System.out.println("3. View Transaction History");
                System.out.println("4. Exit");
                //Get option
                int option = getInt("Please select an option");
                switch (option) {
                    case 1:
                        viewAccounts();
                        break;
                    case 2:
                        transactions();
                        break;
                    case 3:
                        viewTransactions();
                        break;
                    case 4:
                        exit = true;
                        break;
                    default:
                        System.out.println("Invalid Selection");
                        break;
                }
            }
        }

    }

    private void viewAccounts() {
        Collection<Account> accounts = accountFacade.getAccountList(custID, true);
        //Loop through accounts
        ConsoleTable ct = ConsoleTable.getAccountTable();
        for (Account acc : accounts) {
            String[] details = new String[5];
            details[0] = acc.getAccountId().toString();
            details[1] = String.valueOf(acc.getAccountType());
            details[2] = Integer.toString(acc.getAccountBalance());
            details[3] = Integer.toString(acc.getAccountCustomerId().getCustId());
            details[4] = acc.getIsdisabled();
            ct.addRow(details);
        }
        //Print page by page
        for (int x = 0; x < ct.getNoOfPages(); x++) {
            ct.printPagedTable(x);
            System.out.println("Press enter for next page");
            scan.nextLine();
        }
    }

    private void transactions() {
        boolean back = false;
        while (!back) {
            //Print main menu
            System.out.println("");
            System.out.println("Transaction Menu");
            System.out.println("1. Deposit");
            System.out.println("2. Withdrawl");
            System.out.println("3. Transfer");
            System.out.println("4. Back");
            //Get option
            int option = getInt("Please select an option");
            switch (option) {
                case 1:
                    deposit();
                    break;
                case 2:
                    withdrawl();
                    break;
                case 3:
                    transfer();
                    break;
                case 4:
                    back = true;
                    break;
                default:
                    System.out.println("Invalid Selection");
                    break;
            }
        }
    }

    private void deposit() {
        //Get account to deposit in to
        int accId = getInt("Account to deposit in to");
        Account acc = accountFacade.find(accId);
        if (acc != null) {
            //Get ammount to deposit
            int depositAmmount = getInt("Deposit how much (cents)");
            //Get description
            String description = getString("Trasaction description");
            Accounttransaction transaction = accountTransactionHelper.createDeposit(depositAmmount, description, accId);
            if (transaction != null) {
                System.out.println("Transaction completed sucessfully");
            } else {
                System.out.println("Error performing transaction");
            }
        } else {
            System.out.println("No account found with ID: " + accId);
        }
    }

    private void withdrawl() {
        //Get account to withdraw from
        int accId = getInt("Account to withdraw from");
        Account acc = accountFacade.find(accId);
        if (acc != null) {
            //Check customer owns account
            if (acc.getAccountCustomerId().getCustId() != custID) {
                System.out.println("Account " + acc.getAccountCustomerId().getCustId() + " is not your account");
                return;
            }
            //Get ammount to withdraw
            int depositAmmount = getInt("Withdraw how much (cents)");
            //Get description
            String description = getString("Trasaction description");
            Accounttransaction transaction = accountTransactionHelper.createWithdrawl(depositAmmount, description, accId);
            if (transaction != null) {
                System.out.println("Transaction completed sucessfully");
            } else {
                System.out.println("Error performing transaction");
            }
        } else {
            System.out.println("No account found with ID: " + accId);
        }
    }

    private void transfer() {
        //Get from account
        int fromAccId = getInt("Account to transfer from");
        Account fromAcc = accountFacade.find(fromAccId);
        if (fromAcc != null) {
            //Check account belongs to customer
            if (fromAcc.getAccountCustomerId().getCustId() != custID) {
                System.out.println("Account " + fromAcc.getAccountCustomerId().getCustId() + " is not your account");
                return;
            }
            int toAccId = getInt("Acccount to transfer to");
            Account toAcc = accountFacade.find(toAccId);
            if (toAcc != null) {
                //Get amount to transfer
                int amount = getInt("Transfer how much (cents)");
                String description = getString("Transaction Description");
                Accounttransaction transaction = accountTransactionHelper.createTransfer(amount, description, fromAccId, toAccId);
                if (transaction != null) {
                    System.out.println("Transaction completed sucessfully");
                } else {
                    System.out.println("Error performing transaction");
                }
            } else {
                System.out.println("No account found with ID: " + toAccId);
            }
        } else {
            System.out.println("No account found with ID: " + fromAccId);
        }
    }
    
    private void viewTransactions() {
        //Get account ID
        int accID = getInt("Account ID");
        Account account = accountFacade.find(accID);
        if (account != null) {
            //Check account is owned by customer
            if (account.getAccountCustomerId().getCustId() != custID) {
                System.out.println("Account " + account.getAccountId() + " is not your account");
                return;
            }
            List<Accounttransaction> transactions = accountTransactionHelper.getTransactionsForAccount(account);
            ConsoleTable ct = ConsoleTable.getTransactionTable();
            System.out.println("no of trans: " + transactions.size());
            for (Accounttransaction transaction : transactions) {
                String[] details = new String[7];
                details[0] = Integer.toString(transaction.getTransId());
                details[1] = Character.toString(transaction.getTransType());
                //Format the date
                SimpleDateFormat formatter = new SimpleDateFormat("d/M/y H:m:s");
                details[2] = formatter.format(transaction.getTransDate());
                details[3] = Integer.toString(transaction.getTransAmount());
                details[4] = transaction.getTransDescription();
                //Null check on to and from account
                if (transaction.getTransFromAccount() != null) {
                    details[5] = Integer.toString(transaction.getTransFromAccount().getAccountId());
                } else {
                    details[5] = "";
                }
                if (transaction.getTransToAccount() != null) {
                    details[6] = Integer.toString(transaction.getTransToAccount().getAccountId());
                } else {
                    details[6] = "";
                }
                ct.addRow(details);
            }
            //Print page by page
            for (int x = 0; x < ct.getNoOfPages(); x++) {
                ct.printPagedTable(x);
                System.out.println("Press enter for next page");
                scan.nextLine();
            }
        } else {
            System.out.println("Account not found");
        }
    }

    //Get an int, block until provided
    private int getInt(String request) {
        int input = 0;
        while (true) {
            try {
                System.out.print(request + ": ");
                input = Integer.parseInt(scan.nextLine());
                break;
            } catch (NumberFormatException ex) {
                System.out.println("Please enter a number");
            }
        }
        return input;
    }

    //Get a string
    private String getString(String request) {
        System.out.print(request + ": ");
        return scan.nextLine();
    }

    //Get a boolean
    private boolean getBoolean(String request) {
        boolean bool;
        while (true) {
            System.out.println(request + ": ");
            String input = scan.nextLine();
            if (input.equalsIgnoreCase(Boolean.TRUE.toString())) {
                bool = true;
                break;
            } else if (input.equalsIgnoreCase(Boolean.FALSE.toString())) {
                bool = false;
                break;
            }
            System.out.println("Please enter 'true' or 'false'");
        }
        return bool;

    }

    //Get a Customer or Biller char
    private char getCustOrBiller() {
        char type;
        while (true) {
            System.out.print("Please enter 'C' or 'B' for Customer of Biller: ");
            String input = scan.nextLine();
            if (input.isEmpty() || input.charAt(0) == 'c' || input.charAt(0) == 'C') {
                type = 'C';
                break;
            } else if (input.isEmpty() || input.charAt(0) == 'b' || input.charAt(0) == 'B') {
                type = 'B';
                break;
            }
        }
        return type;
    }
}
